//go:generate go tool wit-bindgen-go generate --world echo --out gen ./wit

package main

import (
	"encoding/json"
	"io"
	"net/http"
	"strings"

	"go.wasmcloud.dev/component/log/wasilog"
	"go.wasmcloud.dev/component/net/wasihttp"
)

// A struct containing information about a request,
// sent back as a response JSON from the echo server
type EchoResponse struct {
	Method      string `json:"method"`
	Path        string `json:"path"`
	QueryString string `json:"query_string,omitempty"`
	Body        string `json:"body,omitempty"`
}

func init() {
	// mg := new(Echo)
	// echo.SetExportsWasiHttp0_2_0_IncomingHandler(mg)
	wasihttp.HandleFunc(echoHandler)
}

// Implementation of the `wasi-http:incoming-handler` export in the `echo` world (see `wit/echo.wit)`
//
// This method's signature and implementation use code generated by `wit-bindgen`, in the `gen` folder
// When building with `wash build`, `wit-bindgen` is run automatically to generate the classes that have been aliased above.
func echoHandler(w http.ResponseWriter, r *http.Request) {
	logger := wasilog.ContextLogger("handle")
	er := new(EchoResponse)

	// Use request method to build EchoResponse
	er.Method = r.Method

	// Split the path to retrieve the query element, building the EchoResponse object
	splitPathQuery := strings.Split(r.URL.RequestURI(), "?")
	er.Path = splitPathQuery[0]
	if len(splitPathQuery) > 1 {
		er.QueryString = splitPathQuery[1]
	}

	// Make sure we send back the correct content-type regardless of success or error.
	w.Header().Add("Content-Type", "application/json")

	// Consume the request body
	body, err := io.ReadAll(r.Body)
	if err != nil {
		http.Error(w, err.Error(), http.StatusInternalServerError)
		return
	}
	er.Body = string(body)

	// Log information about the request before we respond
	logger.Debug("request diagnostics", "method", er.Method, "path", er.Path, "queryString", er.QueryString, "body", er.Body)

	w.WriteHeader(http.StatusOK)

	// Marshal the EchoResponse object we've been building to JSON
	err = json.NewEncoder(w).Encode(er)
	if err != nil {
		http.Error(w, err.Error(), http.StatusInternalServerError)
		return
	}
}

func main() {}
